{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "865c7ba2",
   "metadata": {},
   "source": [
    "## 2.3 概率相关知识"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "070656cd",
   "metadata": {},
   "source": [
    "概率统计也是很多人学生时代的噩梦，学习的时候似懂非懂，一头雾水，考试的时候生搬硬套，死记硬背。考试过后，就把知识还给老师了。最终，概率统计也成为了你挂科概率最高的一门学科。\n",
    "\n",
    "为什么概率这么难？这门学科和前面讲过的线性代数、微积分一样，他们都是非直观的理论。不像我们学习开车，转动转动方向盘就能直观看到车子行进方向的改变，学习物理，接通电路就能看到发亮的灯泡。学习概率，我们无法利用自己的直觉和感受去做出归纳，只能由老师将难以理解的抽象的原理写成一个个符号，灌输到我们的大脑中。\n",
    "\n",
    "其实，我们大脑的有两种学习的方法，一种是依靠直觉、本能、感性的快学习；另一种是需要深思熟虑、理性思考、有条不紊的慢学习。第二种很慢，也很难，它需要能量、意志力。因为概率论是非直观性的，所以它注定要在慢学习系统的模式中煎熬的前进。这是它的缺点，但同时，只要你坚持下去，你就会不断体验到它带来的好处，也许某一天的灵光一闪，豁然开朗，就能帮你厘清思路，走出困境。\n",
    "\n",
    "正因如此，对于概率这种抽象概念，时时回顾，多多思考，是很有必要的。学好概率也是学习深度学习必不可少的条件之一，本着奥卡姆剃刀原理，如无必要，勿增新知，这节课我们就来复习一下概率相关的必备知识。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "037ddda8",
   "metadata": {},
   "source": [
    "### 2.3.1 深度学习中的概率"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8a5c1884",
   "metadata": {},
   "source": [
    "在深度学习中，概率可以用来描述神经网络对输入数据的预测结果。例如，一个神经网络可以用来预测图像中是否包含狗，它可以输出一个概率值，表示图像中包含狗的概率。比如下面这三张图片，随着分辨率的提高，我们判断图像中包含狗的概率也在提升。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e1ed0bd6",
   "metadata": {},
   "source": [
    "<img src=\"./images/2-3-1.png\"  ></img>\n",
    "<img src=\"./images/2-3-2.png\"  ></img>\n",
    "<img src=\"./images/2-3-3.png\" width=\"60%\" ></img>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "43620565",
   "metadata": {},
   "source": [
    "概率同样可以用来计算深度学习模型的错误率。在分类问题中，通常希望模型能够尽可能准确地预测类别。因此，我们可以计算模型在测试数据上的错误率，即模型预测错误的概率。这个概率越低，模型的准确率就越高。\n",
    "\n",
    "此外，在训练神经网络时，通常使用概率来计算模型对训练数据的损失。损失函数反映了模型预测结果与实际结果之间的差异。通常我们使用一种称为交叉熵的损失函数来度量模型的预测概率与实际结果之间的差异。\n",
    "\n",
    "在深度学习中，概率还可以用来表示模型的不确定性。如果一个模型在预测图像中是否包含狗时输出了一个很低的概率值，那么这个模型可能并不确定是否真的包含狗，因为它对这个结果的不确定性很高。这种不确定性可以用来帮助我们理解模型的行为，并且可以用来指导模型的训练和应用。\n",
    "\n",
    "概率可以用来描述模型的预测结果、计算模型的错误率和计算模型的损失，还可以用来表示模型的不确定性，在深度学习中起着举足轻重的作用。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b53eeea0",
   "metadata": {},
   "source": [
    "### 2.3.2 概率和统计"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8d694d84",
   "metadata": {},
   "source": [
    "既然概率如此重要，那么我们该如何计算概率呢？最简单实际的办法是通过统计。举个例子，我们想知道全市居民感染新冠肺炎的概率，那么只要统计一下全市目前有多少人感染，然后用感染人数除以总人数就可以了。\n",
    "\n",
    "但是有些时候，这种全量统计的办法并不可行。比如，我们想知道，全国人民对自己当前收入满意的概率，我们不可能把全国人民聚在一起，挨个问一遍他们是否对自己的收入满意。这种时候，我们通常采用一种统计手段——抽样。在统计学中，我们把从概率分布中抽取样本的过程称为抽样（sampling)。具体操作方法是从全部样本中，抽取一定数量的样本，以抽取样本中计算出来的概率，作为总体概率的估计。比如，我们随机街头采访1000个人，将其中满意的人数除以总人数1000，作为全国人民的收入满意率。\n",
    "\n",
    "当然，这种做法有时候会出现问题，比如，如果我们只从大城市抽样而忽略了偏远山村结果，或者从富人区抽样较多，其他地方抽样较少，那么结果和真实值就会有所偏差，这时候就要调整抽样的方法了。调整的方向有很多，比如随机抽样、分层抽样、整群抽样、系统抽样等等。这些抽样方法，其实对应了深度学习中的数据采样方法。举个例子，比如我们训练了一个生成人脸的GAN网络，如果数据样本中，大部分是白人，极少数是黑人，那么模型生成的人脸就会偏向于白人。这种时候，比起调整算法，可能优化数据集来的更有效。\n",
    "\n",
    "概率在统计学和深度学习中都扮演着重要的角色，可以用来描述随机事件的发生概率、表示数据的分布情况和描述数据的生成过程。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b2dddd86",
   "metadata": {},
   "source": [
    "### 2.3.3 事件"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ea833d48",
   "metadata": {},
   "source": [
    "我们说在统计学中，概率是一种用来描述随机事件发生的可能性的数字度量。那么什么是随机事件呢？随机事件其实是指一个或多个随机试验的结果。例如，在抛硬币的实验中，正面朝上和反面朝上都可以看作是一个事件。\n",
    "\n",
    "事件有几个基本的属性：\n",
    "\n",
    "可能性：指事件发生的概率。\n",
    "\n",
    "确定性：指事件是否必定发生或必定不发生。\n",
    "\n",
    "兼容性：指事件是否可以同时发生。\n",
    "\n",
    "事件的依赖指的是事件的发生情况受到其他事件的影响。例如，在抽奖游戏中，获得一等奖的事件可能会受到抽到一个特殊球的事件的影响。\n",
    "\n",
    "独立事件指的是事件的发生情况与其他事件无关。例如，在抛硬币的实验中，正面朝上和反面朝上的事件是独立的，因为它们之间没有任何联系。\n",
    "\n",
    "总的来说，事件是概率统计中的基本概念，可以用来描述随机试验的结果，并且可以根据其属性来分类。事件的依赖和独立事件则是用来描述事件之间关系的概念。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "62891420",
   "metadata": {},
   "source": [
    "### 2.3.4 概率的计算"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "95e5d48a",
   "metadata": {},
   "source": [
    "假设我们掷骰子，想知道掷出1的几率有多大，该怎么算呢？ 如果骰子的质地均匀，那么1-6这六个结果都有相同的可能发生，因此我们可以说掷出1这个事件发生的概率为$\\frac{1}{6}$。\n",
    "\n",
    "然而实际应用中，比如和一群人玩飞行棋，我们不知道是否有人会在骰子上作弊。那么检查骰子的唯一方法是多次投掷并记录结果。 对于每个骰子，每次投掷将观察到一个结果。 对于每个结果，大家自然能够想到的方法是将它出现的次数除以投掷的总次数，作为此事件（event）概率的估计值。大数定律（law of large numbers）告诉我们： 随着投掷次数的增加，这个估计值会越来越接近真实的潜在概率。我们可以通过代码复现这一过程。\n",
    "\n",
    "在统计学中，把从概率分布中抽取样本的过程称为抽样（sampling）。 笼统来说，可以把分布（distribution）看作对事件的概率分配。 将概率分配给一些离散选择的分布称为多项分布（multinomial distribution）。\n",
    "\n",
    "为了抽取一个样本，即掷骰子，我们只需传入一个概率向量。 输出是另一个相同长度的向量：它在索引i处的值是采样结果中i出现的次数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "e23f688d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([0., 0., 0., 1., 0., 0.])"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import torch\n",
    "from torch.distributions import multinomial\n",
    "probs = torch.ones([6]) / 6\n",
    "multinomial.Multinomial(1, probs).sample()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "11beb9cd",
   "metadata": {},
   "source": [
    "在估计一个骰子的公平性时，我们希望从同一分布中生成多个样本。 如果用Python的for循环来完成这个任务，速度会慢得惊人。 因此我们使用深度学习框架的函数同时抽取多个样本，得到我们想要的任意形状的独立样本数组。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "8c324da7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([1., 2., 1., 2., 1., 3.])"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "multinomial.Multinomial(10, probs).sample()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c49c95a1",
   "metadata": {},
   "source": [
    "现在我们知道如何对骰子进行采样，我们可以模拟1000次投掷。 然后，我们可以统计1000次投掷后，每个数字被投中了多少次。 具体来说，我们计算相对频率，以作为真实概率的估计。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "1ecad009",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([0.1520, 0.1870, 0.1560, 0.1610, 0.1560, 0.1880])"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "counts = multinomial.Multinomial(1000, probs).sample()\n",
    "counts / 1000"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d4294776",
   "metadata": {},
   "source": [
    "因为我们前面假设是用一个质地均匀的骰子来生成的数据，所以我们知道每个结果的概率都是1/6，约等于0.167。上面输出的估计值看起来都比较接近我们的预期值。而当我们将次数扩增到10000次时，可以看到结果更加的接近了。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "cb7c29b6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([0.1678, 0.1678, 0.1672, 0.1613, 0.1691, 0.1668])"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "counts = multinomial.Multinomial(10000, probs).sample()\n",
    "counts / 10000"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b074d483",
   "metadata": {},
   "source": [
    "### 2.3.5 随机变量"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0341369e",
   "metadata": {},
   "source": [
    "我们在掷骰子的随机实验中，引入和随机变量的概念。随机变量是概率统计中用来表示随机事件结果的变量。它可以用来描述随机事件的结果的分布情况，并且可以用来计算概率。\n",
    "\n",
    "随机变量有两种类型：\n",
    "\n",
    "离散随机变量（discrete）：指随机变量取值为有限个或无限个离散值的变量。例如，在抛硬币的实验中，随机变量可以是正面朝上次数，取值范围为{0,1,2,...}。\n",
    "\n",
    "连续随机变量（continuous）：指随机变量取值为连续值的变量。例如，在测量人体身高的实验中，随机变量可以是人的身高，取值范围为[0,+∞)。\n",
    "\n",
    "通常使用概率分布来描述随机变量的分布情况。例如使用正态分布来描述一组数据的分布情况，或者使用泊松分布来描述一组事件发生的频率分布情况。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5d6c48b9",
   "metadata": {},
   "source": [
    "### 2.3.6 概率密度"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "31c9eacb",
   "metadata": {},
   "source": [
    "离散随机变量和连续随机变量之间有时候也可以相互转化。 现实生活中，测量两个人是否具有完全相同的身高没有太大意义。 如果我们进行足够精确的测量，最终会发现世界上没有两个人具有完全相同，分毫不差的身高。 在这种情况下，询问某人的身高是否落入给定的区间，比如是否在1.79米和1.81米之间更有意义。 在这些情况下，我们将这个看到某个数值的可能性量化为密度（density）。 \n",
    "\n",
    "概率密度（probability density）是一种描述概率分布的函数。它表示在某一区间内取一个特定值的概率。\n",
    "\n",
    "比如说，假设有一个随机变量X，它的概率密度函数为f(x)。那么，X在区间[a,b]内取到某个特定值x的概率就是f(x)在区间[a,b]内的积分。\n",
    "\n",
    "对于连续随机变量，概率密度函数是其分布函数的导数。分布函数是描述随机变量小于等于某个值的概率的函数。\n",
    "\n",
    "例如，假设X是一个服从正态分布的连续随机变量，那么它的概率密度函数就是一个常见的高斯函数，表示为：\n",
    "\n",
    "$$ f(x)=(\\frac{1}{\\sqrt{2\\pi\\sigma^2}} )\\mathrm{exp} (-\\frac{x-\\mu^2}{2\\sigma^2}) $$\n",
    "\n",
    "在这个式子中，$\\mu$是X的期望值，$\\sigma$是X的标准差，$\\pi$是圆周率，exp是指数函数。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bce68c0e",
   "metadata": {},
   "source": [
    "### 2.3.7 联合概率和条件概率"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4a258f63",
   "metadata": {},
   "source": [
    "联合概率是指同时发生两个或多个事件的概率。联合概率可以用来计算两个或多个事件发生的概率，并且可以用来分析事件之间的关系。\n",
    "\n",
    "条件概率是指在某个条件下发生某个事件的概率。条件概率可以用来表示一个事件发生的条件，并且可以用来计算在某个条件下发生某个事件的概率。\n",
    "\n",
    "联合概率和条件概率之间有如下关系：\n",
    "\n",
    "联合概率可以用来计算条件概率。例如，设事件A和事件B同时发生的概率为P(A,B)，事件B发生的概率为P(B)，则在事件B发生的条件下事件A发生的概率为\n",
    "$$ P(A|B)= \\frac{P(A,B)}{P(B)} $$\n",
    "\n",
    "条件概率可以用来计算联合概率。例如，设在事件B发生的条件下事件A发生的概率为P(A|B)，事件B发生的概率为P(B)，则事件A和事件B同时发生的概率为\n",
    "$$ P(A,B)=P(A|B)P(B) $$\n",
    "\n",
    "总的来说，联合概率和条件概率是概率统计中的重要概念，可以用来计算两个或多个事件发生的概率，并且可以用来分析事件之间的关系。联合概率和条件概率之间有着密切的关系，可以相互转化。\n",
    "\n",
    "举个例子，在掷骰子的实验中，设掷骰子结果是1的事件为A，选择的骰子恰好质地均匀的事件为B，则联合概率和条件概率可以表示为：\n",
    "\n",
    "$P(A,B)$：选择的骰子恰好质地均匀和掷骰子结果是1同时发生的概率。\n",
    "\n",
    "$P(A|B)$：在选择的骰子恰好质地均匀的条件下掷骰子结果是1发生的概率。\n",
    "\n",
    "$P(B|A)$：在掷骰子结果是1条件下选择的骰子恰好质地均匀的概率。\n",
    "\n",
    "可以看出，联合概率和条件概率是可以互相转化的。例如:\n",
    "$$P(A|B)=P(A,B)/P(B)$$\n",
    "$$P(A,B)=P(A|B)P(B)$$\n",
    "\n",
    "总的来说，联合概率和条件概率是概率统计中的重要概念，可以用来计算两个或多个事件发生的概率，并且可以用来分析事件之间的关系。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cd7d6c6c",
   "metadata": {},
   "source": [
    "### 2.3.8 贝叶斯定理"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0a558ab6",
   "metadata": {},
   "source": [
    "贝叶斯定理是统计学中最有用的方程之一，它是指在已知条件概率的情况下，可以推导出联合概率。贝叶斯定理是概率统计中的重要定理，常用于根据已知信息推测未知信息的场景。\n",
    "\n",
    "贝叶斯定理的公式为：\n",
    "\n",
    "$$P(A|B)=\\frac{P(B|A)P(A)}{P(B)}$$\n",
    "\n",
    "其中，P(A|B)表示在事件B发生的条件下事件A发生的概率，P(B|A)表示在事件A发生的条件下事件B发生的概率，P(A)表示事件A发生的概率，P(B)表示事件B发生的概率。\n",
    "\n",
    "举个例子来说明贝叶斯定理，还是看我们前面讲过的例子，假设掷骰子为1的概率为P(X=1), 骰子质地均匀的概率为 P(均匀)，那么在骰子质地均匀的情况下，掷一次骰子结果为1的概率就可以表示如下：\n",
    "\n",
    "$$P(X=1|均匀)=\\frac{P(均匀|X=1)P(X=1)}{P(均匀)} $$\n",
    "\n",
    "为了能进行事件概率求和，我们需要求和法则（sum rule）， 即骰子质地均匀的概率相当于计算掷出结果的所有可能选择，并将所有选择的联合概率聚合在一起：\n",
    "\n",
    "$$ P(均匀)=\\sum_{i=1}^{6}P(X=i,均匀) $$\n",
    " \n",
    "这也称为边际化（marginalization）。 边际化结果的概率或分布称为边际概率（marginal probability） 或边际分布（marginal distribution）"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "661021b9",
   "metadata": {},
   "source": [
    "### 2.3.9 期望和方差"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ae95a8db",
   "metadata": {},
   "source": [
    "期望是指随机变量的概率分布的平均值。期望可以用来衡量一个随机变量的中间值，并且可以用来分析随机变量的取值分布情况。\n",
    "\n",
    "方差是指随机变量的期望与其取值的偏差的平方的期望。方差可以用来衡量一个随机变量的离散程度，并且可以用来分析随机变量的取值分布情况。\n",
    "\n",
    "期望和方差的计算公式分别为：\n",
    "\n",
    "期望：$E(X)=∑xP(x)$\n",
    "\n",
    "方差：$Var(X)=E((X-E(X))^2)=E(X^2)-E(X)^2$\n",
    "\n",
    "其中，E(X)表示随机变量X的期望，P(x)表示随机变量X取值为x的概率，Var(X)表示随机变量X的方差。\n",
    "\n",
    "举个例子来说明期望和方差的计算，假设有一个随机变量X，取值和概率分别为："
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c515dac7",
   "metadata": {},
   "source": [
    "<img src=\"./images/2-3-4.png\" width=\"70%\" ></img>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "282e9d58",
   "metadata": {},
   "source": [
    "根据期望的计算公式，随机变量X的期望为：\n",
    "\n",
    "$$ E(X)=∑xP(X=x)=1\\times0.1+2\\times0.2+3\\times0.3+4\\times0.4 = 3 $$\n",
    "\n",
    "根据方差的计算公式，随机变量X的方差为：\n",
    "\n",
    "$$Var(X)=E((X-E(X))^2)=E(X^2)-E(X)^2=1\\times1\\times0.1+2\\times2\\times0.2+3\\times3\\times0.3+4\\times4\\times0.4 - 3^2= 1$$\n",
    "\n",
    "由此可以看出，随机变量X的期望为3，方差为1。\n",
    "\n",
    "总的来说，期望和方差是概率统计中的重要概念，可以用来分析随机变量的取值分布情况。期望可以衡量随机变量的中间值，方差可以衡量随机变量的离散程度。期望和方差的计算可以帮助我们了解随机变量的取值范围，并且可以用来分析随机变量的变化趋势。\n",
    "\n",
    "在深度学习中，期望和方差也是重要的概念。例如，在训练神经网络时，可以利用期望和方差来调整权值和偏置，使得训练结果更加精确。此外，期望和方差还可以用来分析模型的泛化能力，从而更好地调整模型的参数。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "71143d9d",
   "metadata": {},
   "source": [
    "[Next 3-1深度学习环境配置](../Chapter-03%20环境安装和工具使用/3-1%20%5BCUDA%2BAnaconda%5D深度学习环境配置.ipynb)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0b51bcd7",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
